package com.easyJava.bean;

import com.easyJava.builder.BuildMapper;
import com.easyJava.builder.BuildMapperXml;
import javafx.scene.control.Tab;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.omg.CORBA.PUBLIC_MEMBER;

import java.io.BufferedWriter;
import java.util.List;

public class XmlConstants {
    public static final String CDATA = "<![CDATA[ and  ";
    public static final String STR_TO_DATE = "str_to_date";
    public static final String XML_DATE = "'%Y-%m-%d'";
    public static final String WHERE = "where";
    public static final String INCLUDE_REFID = "include refid";
    public static final String AND = "and";
    public static final String CONCAT = "concat";
    public static final String BEFORE_DAY = "interval -1 day";
    public static final String LIKE = "like";
    public static final String SELECT = "select";
    public static final String QUERY_COLLECTIONS_COMMENT = "查询集合";
    public static final String QUERY_COLLECTIONS_ID = "selectList";
    public static final String REFID = "refid";
    public static final String INCLUDE = "include";
    public static final String FROM = "from";
    public static final String IF = "if ";
    public static final String ORDER = "order";
    public static final String BY = "by ";
    public static final String LIMIT = "limit";
    public static final String START = "start";
    public static final String END = "end";
    public static final String QUERY_COUNT_COMMENT = "查询数量";
    public static final String INSERT_COMMENT = "插入(匹配有值的字段)";
    public static final String INSERT_COMMENT_ID = "insert";
    public static final String INSERT_NAME = "insert";
    public static final String PARAMETERTYPE = "parameterType";
    public static final String SELECTKEY = "selectKey";
    public static final String KEYPROPERTY = "keyProperty";
    public static final String LAST_INSERT_ID = "LAST_INSERT_ID()";
    public static final String INSERT_AFTER = "AFTER";
    public static final String TRIM = "trim";
    public static final String PREFIX = "prefix";
    public static final String SUFFIX = "suffix";
    public static final String SUFFIXO_VERRIDES = "suffixOverrides";
    public static final String INSERT_SQL = "insert into ";
    public static final String INSERTORUPDATE = "insertOrUpdate";
    public static final String ONDUPLICATEKEYUPDATE = "on DUPLICATE key update ";
    public static final String INSERTBATCH = "insertBatch";
    public static final String USEGENERATEDKEYS = "useGeneratedKeys";
    public static final String COLLECTION = "collection";
    public static final String ITEM = "item";
    public static final String FOREACH = "foreach";
    public static final String values = "values";
    public static final String insertOrUpdate_COMMENT = "插入或者更新 （匹配有值的字段）";
    public static final String COLLECTION_LIST = "list";
    public static final String ITEM_NAME = "item";
    public static final String SEPARATOR = "separator";
    public static final String INSERTBATCH_COMMENT = "添加 （批量插入）";
    public static final String insertOrUpdateBatch_COMMENT = "批量新增修改 （批量插入）";
    public static final String INSERTORUPDATEBATCH = "insertOrUpdateBatch";
    public static final String UPDATEBYPARAM = "updateByParam";
    public static final String UPDATE_BYPARAM_COMMENT = "多条件修改";
    public static final String SET = "set";
    public static final String UPDATE = "update";
    public static final String DELETE = "delete";
    public static final String DELETE_BY_PARAM = "deleteByParam";
    public static final String DELETE_BY_PARAM_COMMENT = "多条件删除";
    public static final String UPDATE_BY_ID = "updateById";
    public static final String UPDATE_BY_ID_COMMENT = "根据Id修改";
    public static final String DELETE_BY_ID = "deleteById";
    public static final String DELETE_BY_ID_COMMENT = "根据Id删除";
    public static final String SELECT_BY_ID = "selectById";
    public static final String SELECT_BY_ID_COMMENT = "根据Id查询";


    /**
     *  处理where
     * @param bw
     * @param fieldInfosList
     * @throws Exception
     */
    public static void WhereKey(BufferedWriter bw, List<FieldInfo> fieldInfosList) throws Exception{
        bw.write("\t\t" + WHERE +" " );
        for (int i = 0; i < fieldInfosList.size(); i++) {
            bw.write(fieldInfosList.get(i).getFieldName() + "=#{" + fieldInfosList.get(i).getPropertyName() + "}");
            if(i != fieldInfosList.size() -1){
                bw.write(" " + AND + " ");
            }
        }
        bw.write("\n");
    }



    /**
     * 处理set标签
     * @param bw
     * @param tableInfo
     * @throws Exception
     */
    public static void DoSet(BufferedWriter bw,TableInfo tableInfo,List<FieldInfo>KeyList) throws Exception{
        bw.write("\t\t <" + SET + ">\n");
        for(FieldInfo fieldInfo :tableInfo.getFieldInfoList()){
            if(fieldInfo.equals(tableInfo.getKeyFieldInfo())){
                continue;
            }
            if(KeyList.contains(fieldInfo)){
                continue;
            }
            String s = fieldInfo.getFieldName() + " = #{" +Constants.BEAN_NAME + "." +fieldInfo.getPropertyName() +"}";
            TestInTrim(fieldInfo.getPropertyName(),bw,s);
        }
        bw.write("\t\t</" + SET +">\n" );
    }

    /**
     * 生成查询集合
     * @param bw
     * @param tableInfo
     * @throws Exception
     */

    public static void DoForEach(BufferedWriter bw ,TableInfo tableInfo,Boolean DoUpate) throws Exception{
        bw.write("\t\t " + INSERT_SQL + tableInfo.getTableName() + "{"+ "\n");

        //生成key
        for(FieldInfo fieldInfo : tableInfo.getFieldInfoList()){
            if(fieldInfo.equals(tableInfo.getKeyFieldInfo())){
                continue;
            }
            EachValue(bw,fieldInfo.getFieldName());
        }
        bw.write("\t\t}" + values + "\n");

        bw.write("\t\t<" + FOREACH  +" "+ COLLECTION + "=\"" + COLLECTION_LIST + "\" " + ITEM + "=\"" + ITEM_NAME + "\" " + SEPARATOR+ "=\",\">\n");
        bw.write("\t\t\t{\n");

        //生成值
        for(FieldInfo fieldInfo : tableInfo.getFieldInfoList()){
            if(fieldInfo.equals(tableInfo.getKeyFieldInfo())){
                continue;
            }
            EachValue(bw,"\t#{" +ITEM +"." +  fieldInfo.getPropertyName()+"}");
        }

        bw.write("\t\t\t}\n");
        bw.write("\t\t</" + FOREACH + ">\n");
        if(DoUpate){
            bw.write("\t\t\t" + XmlConstants.ONDUPLICATEKEYUPDATE + "\n");
            for(FieldInfo fieldInfo : tableInfo.getFieldInfoList()){
                if(fieldInfo.equals(tableInfo.getKeyFieldInfo())){
                    continue;
                }
                EachValue(bw, fieldInfo.getFieldName() +" = " + values +"(" + fieldInfo.getFieldName() + ")");
            }
        }
    }

    /**
     * 生成插入或者更新
     * @param bw
     * @param fieldName
     * @throws Exception
     */
    public static void EachValue(BufferedWriter bw ,String fieldName) throws Exception{
           bw.write("\t\t\t" + fieldName + ",\n");
    }

    /**
     * 处理trim标签
     * @param bw
     * @param tableInfo
     * @param prefix
     * @param suffix
     * @param suffixOverrides
     * @throws Exception
     */

    public static void TrimDealWith(BufferedWriter bw, TableInfo tableInfo ,String prefix,String suffix,String suffixOverrides,Boolean isKey) throws Exception{
        bw.write("\t\t<" + TRIM +" " + PREFIX + "=\"" + prefix +"\" " + SUFFIX + "=\"" + suffix + "\" " + SUFFIXO_VERRIDES + "=\"" + suffixOverrides + "\">\n");

        for (FieldInfo fieldInfo : tableInfo.getFieldInfoList()){
            //主键不需要插入
            if(fieldInfo.equals(tableInfo.getKeyFieldInfo()) && isKey){
                continue;
            }
            if(prefix.startsWith("(")){
                TestInTrim(fieldInfo.getPropertyName(),bw,fieldInfo.getFieldName());
            }else if(prefix.startsWith("values")){
                TestInTrim(fieldInfo.getPropertyName(),bw,"#{"+Constants.BEAN_NAME+"."+fieldInfo.getPropertyName()+"}");
            }else if("".equals(prefix) && "".equals(suffix)){
                TestInTrim(fieldInfo.getPropertyName(),bw,fieldInfo.getFieldName()+ " = VALUES(" + fieldInfo.getFieldName() +")");
            }
        }
        bw.write("\t\t</" + TRIM + ">\n");
    }

    /**
     *  处理trim中的test标签
     * @param PropertyName
     * @param bw
     * @param FieldName
     * @throws Exception
     */

    public static void TestInTrim(String PropertyName,BufferedWriter bw,String FieldName) throws Exception{
        bw.write("\t\t\t<" + IF  + BuildMapperXml.TEST + "=\"" +Constants.BEAN_NAME + "." + PropertyName + BuildMapperXml.NOTNULL+ "\">\n");
        bw.write("\t\t\t\t" + FieldName + ",\n");
        bw.write("\t\t\t</" + IF + ">\n");
    }


    /**
     * 生成扩展查询集合
     * @param bw
     * @param fieldInfo
     * @throws Exception
     */
    public static void FuzzyDoTest(BufferedWriter bw ,FieldInfo fieldInfo) throws Exception{
        bw.write("\t\t\t<" + IF +" " + BuildMapperXml.TEST + "=\"" +BuildMapperXml.QUERY + fieldInfo.getPropertyName() + BuildMapperXml.NOTNULL + XmlConstants.AND + " " +BuildMapperXml.QUERY + fieldInfo.getPropertyName() + " != ''\">\n");
        String s = new String();
        if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
            s = "\t\t\t\tand " + fieldInfo.getFieldName() + " " + XmlConstants.LIKE+" " + XmlConstants.CONCAT + " ('%', #{" + BuildMapperXml.QUERY + fieldInfo.getPropertyName() + "},'%')\n";
        }else if(ArrayUtils.contains(Constants.SQL_DATE_TYPES,fieldInfo.getSqlType()) || ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())) {
            if(fieldInfo.getPropertyName().endsWith(Constants.query_date_start))
            {
                s = "\t\t\t\t" + XmlConstants.CDATA + fieldInfo.getFieldName() + " >= " + XmlConstants.STR_TO_DATE + "(#{" +BuildMapperXml. QUERY + fieldInfo.getPropertyName() + "}," + XmlConstants.XML_DATE + ") ]]>\n";
            }else if(fieldInfo.getPropertyName().endsWith(Constants.query_date_end)) {
                s = "\t\t\t\t" + XmlConstants.CDATA + fieldInfo.getFieldName() + " < " + XmlConstants.STR_TO_DATE + "(#{" + BuildMapperXml.QUERY + fieldInfo.getPropertyName() + "}," + XmlConstants.XML_DATE + ")," + XmlConstants.BEFORE_DAY + ")" + "]]>\n";
            }
        } bw.write(s);
        bw.write("\t\t\t</" + IF + ">\n");
    }

    /**
     * 生成普通查询集合
     * @param bw
     * @param fieldInfo
     * @throws Exception
     */
    public static void EqualDoTest(BufferedWriter bw , FieldInfo fieldInfo) throws Exception{
        String s  = new String();
        if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
            s = "and " + BuildMapperXml.QUERY+fieldInfo.getPropertyName() + " != ''" ;
        }
        bw.write("\t\t\t<"+IF +" "+BuildMapperXml.TEST + "=\""+ BuildMapperXml.QUERY + fieldInfo.getPropertyName() + BuildMapperXml.NOTNULL + s + "\">\n");
        String result = "\t\t\t\tand " + fieldInfo.getFieldName() + " = #{" +BuildMapperXml.QUERY + fieldInfo.getPropertyName() +"}\n";
        if (ArrayUtils.contains(Constants.SQL_DATE_TYPES,fieldInfo.getSqlType()) || ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,fieldInfo.getSqlType())){
            result = "\t\t\t\t" + XmlConstants.CDATA + fieldInfo.getFieldName() + " = " + XmlConstants.STR_TO_DATE + "(#{" + BuildMapperXml.QUERY + fieldInfo.getPropertyName() + "}," + XmlConstants.XML_DATE + ") ]]>\n";
        }
        bw.write(result);
        bw.write("\t\t\t</"+IF +">\n");
    }


    /**
     * 生成特殊查询IF
     * @param bw
     * @param fieldName
     * @param isEmpty
     * @param action
     * @throws Exception
     */
    public static void SpecialDoTest(BufferedWriter bw,String fieldName ,Boolean isEmpty,String action) throws Exception{
        bw.write("\t\t <" +IF + BuildMapperXml.TEST + "=\"" + fieldName + BuildMapperXml.NOTNULL + "\">\n");
        if(ORDER.equals(action)){
            bw.write("\t\t\t" + ORDER + " "+ BY + " ${" + fieldName + "}\n");
        }
        if(LIMIT.equals(action)){
            bw.write("\t\t\t" + LIMIT + " #{" + fieldName + "." + START + "}" + "," + "#{" + fieldName + "." + END + "}\n"); ;
        }
        bw.write("\t\t</" + IF + ">\n");
    }



}
